package jsimplesim.model;

import java.util.Arrays;

import javax.swing.table.AbstractTableModel;

import org.apache.log4j.Logger;

import jsimplesim.view.JSimpleSimView;

/**
 * 
 * @ALPHA 
 *
 */
 
 
public class StackModel extends AbstractTableModel {
	
	private static final long serialVersionUID = -1100796050866152019L;
	static Logger logger = Logger.getLogger(StackModel.class);
private byte[] stack;
private int numRecords;



public JSimpleSimView view;

/**
 * basic constructor
 */
public StackModel(){
	stack = new byte[256];
	numRecords = 0;
	this.resetStack(stack);
}
/**
 * basic constructor with view
 * @param
 */
public StackModel(JSimpleSimView view1){
	view = view1;
	stack = new byte[256];
	numRecords = 0;
	this.resetStack(stack);
}
/**
 * Clears the stack.
 */
public void resetStack(byte[] stack){
	this.stack = stack;
	fireTableDataChanged();
}
@Override
public String toString() {
	return "StackModel [stack=" + Arrays.toString(stack) + "]";
}
/**
 * Gets the number of activation records on the stack
 * @return
 */
public int getNumRecords(){
	return numRecords;
}


/**
 * Pushes an activation record on the stack
 * @param returnAddress
 */
	public void push(Object returnAddress) {
		String hexString = returnAddress.toString();
		logger.info("hexString = " + hexString);

		if (numRecords >= 255)
			return;

		if (hexString.length() > 0) {
			byte hexByte = (byte) Integer.parseInt(hexString, 10);
			logger.info("hexByte = " + hexByte);
			stack[numRecords] = hexByte;
			logger.info("stack[numRecords] = " + stack[numRecords]);
			this.fireTableDataChanged();
			numRecords++;
		}
	}

/**
 * Pops the top activation record off the stack
 * @return
 */
public void pop(){
	if (numRecords == 0) return;
	stack[--numRecords] = (byte) 00;
	fireTableDataChanged();
}

public int getColumnCount(){
	return 1;
}
public int getRowCount(){
	return numRecords;
}
public Object getValueAt(int row, int col){
	int index = (row);

    if (index < stack.length) {
        return stack[index];
    } else {
        return null;
    }
}

}

/**
 * @author James
 *
 */
class ActivationRecord {
	private static byte RA;
	private static byte firstByte;
	private static byte lastByte;
	private static byte color;
/**
 * Gets the return address from the activation record	
 * @return
 */
	public byte getRA(){
		return RA;
	}
/**
 * Sets the return address for the activation record
 * @param a
 */
	public void setRA(byte a){
		RA = a;
	}
/**
 * Gets the lowest address the activation record occupies in memory
 * @return
 */
	public byte getFirstByte(){
		return firstByte;
	}
/**
 * Sets the lowest address of the activation record
 * @param value
 */
	public void setFirstByte(byte value){
		firstByte = value;
	}
/**
 * Gets the highest address of the activation record
 * @return
 */
	public byte getLastByte(){
		return lastByte;
	}
/**
 * Sets the highest address of the activation record
 * @param value
 */
	public void setLastByte(byte value){
		lastByte = value;
	}
/**
 * Returns the value of the color of the activation record
 * @return
 */
	public byte getColor(){
		return color;
	}
/**
 * Sets the color value of the activation record
 * @param value
 */
	public void setColor(byte value){
		color = value;
	}
	
@Override
public String toString() {
	return "ActivationRecord []";
}
/**
 * Basic constructor
 */
	public ActivationRecord(){
		this((byte)255, (byte)255, (byte)0);
	}
/**
 * General Constructor
 * @param first
 * @param last
 * @param returnAddress
 */	
	public ActivationRecord(byte first, byte last, byte returnAddress){
		this(last, first, returnAddress, (byte)0);
	}
/**
 * Final constructor
 * @param first
 * @param last
 * @param returnAddress
 * @param colorInit
 */
	public ActivationRecord(byte first, byte last, byte returnAddress, byte colorInit){
		firstByte = first;
		lastByte = last;
		RA = returnAddress;
		color = colorInit;
	}
	
}